Skip to content

Fix ordering for UNION ALL over heterogeneous constants#23528

Open
vadimpiven wants to merge 1 commit into
apache:mainfrom
vadimpiven:main
Open

Fix ordering for UNION ALL over heterogeneous constants#23528
vadimpiven wants to merge 1 commit into
apache:mainfrom
vadimpiven:main

Conversation

@vadimpiven

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

  • Closes #.

Rationale for this change

add_sort_above and add_sort_above_with_distribution in physical-optimizer prune every expression that EquivalenceProperties::is_expr_constant reports as constant.
This treats AcrossPartitions::Heterogeneous the same as AcrossPartitions::Uniform, which is incorrect.

Check an example:

SELECT 2 AS sample, c FROM t
UNION ALL
SELECT 1 AS sample, c FROM t
ORDER BY sample, c

The union reports sample as a Heterogeneous constant and so it gets pruned, which breaks ORDER BY.

What changes are included in this PR?

Helper that activates pruning only for AcrossPartitions::Uniform, use it at both prune sites (add_sort_above and add_sort_above_with_distribution) so Heterogeneous constants are retained.

Are these changes tested?

Yes, a new unit-test added.

Are there any user-facing changes?

No API changes, just an internal logic bug-fix.

`add_sort_above` and `add_sort_above_with_distribution` pruned every
expression that equivalence properties reported as constant, via
`is_expr_constant(..).is_none()`. That treats `AcrossPartitions::Heterogeneous`
the same as `AcrossPartitions::Uniform`, which is wrong.

A `Heterogeneous` constant is constant *within* each partition but varies
*across* partitions (e.g. `sample` in
`SELECT 1 AS sample, c FROM t UNION ALL SELECT 2 AS sample, c FROM t`).
Both helpers build a partition-preserving `SortExec` whose output is merged
across partitions downstream, where such a column is still the leading
ordering discriminator. Dropping it silently discards the global ordering,
producing non-deterministic output order for `ORDER BY sample, c` once the
plan is rooted at a sink / output requirement.

Only `AcrossPartitions::Uniform` is globally constant and safe to drop.
Introduce `is_uniform_constant` and use it at both prune sites.

Adds a regression test that builds a union with a heterogeneous-constant
column and asserts the key survives `add_sort_above`.
@github-actions github-actions Bot added the optimizer Optimizer rules label Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

optimizer Optimizer rules

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant